image.png

Caso Monopoly¶

monopoly.webp

Integrantes:

  • Sebastian Orellana
  • Ignacio Pi

Entrega 1¶

  • 1.-Utiliza la metodología CRISP-DM con su correcta identación dentro del Notebook.
  • 2.-Identifica un target para la tarea de "regresión". CUPO_L1
  • 3.-Identifica un target para la tarea de "clasificación". SUBSEGMENTO
  • 4.-Utiliza librerías Numpy, ScikitLearn, matplotlib y seaborn.
  • 5.-Realiza limpieza y preparación de los datos de forma adecuada.
  • 6.-Elabora documentación del proceso (información del caso y de los datos).
  • 7.-Aplica tratamiento a los datos atípico y datos perdidos (imputación de los datos).
  • 8.-Usa estadísticos de tendencia central y de dispersión para explorar los datos.
  • 9.-Propone normalizaciones o estandarización según sea necesario.
  • 10.-Justifica "en texto" dentro del notebook cada técnica utilizada en el proceso.

Caso Fundamentos de Machine Learning¶

CONTEXTO CASO

Caso Banco “Monopoly/Dormammu” El banco Monopoly lleva muchos años atendiendo a sus clientes en Chile y recientemente ha sido adquirido por un Banco con capitales extranjeros llamado “Dormammu”. Dormammu ha encargado a sus ingenieros hacer estudios sobre los clientes del banco Monopoly, para conocer su comportamiento y detectar patrones. Además, debe analizar cómo será su estrategia para abordar estos nuevos clientes dado el uso que ellos hacen de sus productos financieros. Los ingenieros del área informática del banco Monopoly han extraído una base de datos según una solicitud recibida por el nuevo dueño del banco y la han compartido con los ingenieros de Dormammu que están en la sede de New York. La base contiene una muestra de clientes con 12 meses de información almacenada en variables mensuales por cada cliente. Usted es parte del equipo de ingenieros del banco Dormammu, y con sus colegas debe analizar esta base, limpiarla, seleccionar las variables que sirvan para alguna interpretación y entregar la mayor información posible a los dueños de este banco para que puedan conocer a los clientes, preparar una estrategia y abordar a este nuevo mercado. La base de datos tiene variables asociadas a información del cliente y variables mensuales, es decir una por cada mes, el cliente no se repite y las variables asociadas se van agregando como una columna más. Con esto, la base de datos tiene 574 variables y 51.124 registros. La descripción de las variables se muestra a continuación:

Variable Transformación Descripcion
CORRELATIVO Ninguna Identificador cliente
Region Ninguna Region de Residencia
Renta Ninguna Renta del cliente
Sexo Ninguna Sexo
Subsegmento Ninguna Subsegmento
Edad Ninguna Edad
Adicional Ninguna Indicador de Tenecia de TC adicionales
Antiguedad Ninguna Antigüedad del cliente (meses)
CambioPin Ninguna Indicador del cambio de clave secreta de la tarjeta
Consumo Ninguna Indicador de Credito de Consumo
Debito Ninguna Indicador de Tenecia de TD
Ctacte Ninguna Indicador de Cuenta Corriente
Cuentas Ninguna Numero de cuentas que tiene el cliente
Hipotecario Ninguna Indicador de Credito Hipotecario
Internauta Ninguna Indicador de cliente Internauta que usa la web Monopoly
Monoproducto Ninguna Indicador de si el cliente es solo poseedor de una TC
TC Ninguna Numero de TC que tiene el cliente
Dualidad Ninguna Indicador de Dualidad (Cliente es dual si tiene 2 o mas TC)
CUPO_L1 Ninguna Cupo de la tarjeta credito para compras nacionales
CUPO_MX Ninguna Cupo de la tarjeta credito para compras internacionales
CUPO_L2 Ninguna Cupo de la tarjeta credito para avances en cuotas
Col_T12 promedio Colocacion del cliente en TC en el mes X
ColL1TE_T12 Revolving del cliente en TC en el mes X
EeccInt_T12 promedio Monto internacional exigido en el estado de cuenta del cliente en el mes X
EeccNac_T12 promedio Monto nacional exigido en el estado de cuenta del cliente en el mes X
Fac_T12 Promedio Monto facturado por el cliente en TC en el mes X
FacAI_T12 Promedio Monto facturado en avances internacionales por el cliente en TC en el mes X
FacAN_T12 Promedio Monto facturado en avances nacionales por el cliente en TC en el mes X
FacCCOT_T12 Promedio Monto facturado en compras en cuotas con tasa por el cliente en TC en el mes X
FacCCPC_T12 Promedio Monto facturado en compras en cuotas precio contado por el cliente en TC en el mes X
FacCI_T12 Promedio Monto facturado en compras internacionales por el cliente en TC en el mes X
FacCN_T12 Promedio Monto facturado en compras nacionales por el cliente en TC en el mes X
FacCOL_T12 Promedio Monto facturado en avances en cuotas por el cliente en TC en el mes X
FacDebAtm_T12 Promedio Monto facturado en avances por el cliente en TD en el mes X
FacDebCom_T12 Promedio Monto facturado en compras por el cliente en TD en el mes X
FacPAT_T12 Promedio Monto facturado en PAT por el cliente en TC en el mes X
FlgAct_T12 Suma meses activos Indicador de actividad en el mes X en la TC
FlgActAI_T12 Suma meses activos Indicador de actividad en avances internacionales en el mes X en la TC
FlgActAN_T12 Suma meses activos Indicador de actividad en avances nacionales en el mes X en la TC
FlgActCCOT_T12 Suma meses activos Indicador de actividad en compras nacionales en cuotas con tasa en el mes X en la TC
FlgActCCPC_T12 Suma meses activos Indicador de actividad en compras nacionales en cuotas precio contado en el mes X en la TC
FlgActCI_T12 Suma meses activos Indicador de actividad en compras internacionales en el mes X en la TC
FlgActCN_T12 Suma meses activos Indicador de actividad en compras nacionales en el mes X en la TC
FlgActCOL_T12 Suma meses activos Indicador de actividad en avances en cuotas con tasa en el mes X en la TC
FlgActPAT_T12 Suma meses activos Indicador de actividad en PAT en el mes X en la TC
PagoInt_T12 promedio Monto de pagos de deuda internacional del cliente en el mes X
PagoNac_T12 promedio Monto de pagos de deuda nacional del cliente en el mes X
Txs_T12 Suma Numero de transacciones realizados por el cliente en TC en el mes X
TxsAI_T12 Suma Numero de transacciones en avances internacionales realizados por el cliente en TC en el mes X
TxsAN_T12 Suma Numero de transacciones en avances nacionales realizados por el cliente en TC en el mes X
TxsCCOT_T12 Suma Numero de transacciones en compras en cuotas con tasa realizados por el cliente en TC en el mes X
TxsCCPC_T12 Suma Numero de transacciones en compras en cuotas precio contado realizados por el cliente en TC en el mes X
TxsCI_T12 Suma Numero de transacciones en compras internacionales realizados por el cliente en TC en el mes X
TxsCN_T12 Suma Numero de transacciones en compras nacionales realizados por el cliente en TC en el mes X
TxsCOL_T12 Suma Numero de transacciones en avances en cuotas por el cliente en TC en el mes X
TxsDebAtm_T12 Suma Numero de transacciones en avances realizados por el cliente en TD en el mes X
TxsDebCom_T12 Suma Numero de transacciones en compras realizados por el cliente en TD en el mes X
TxsPAT_T12 Suma Numero de transacciones en PAT realizados por el cliente en TC en el mes X
UsoL1_T12 Promedio Monto de deuda en la linea de compras en la TC en el mes X
UsoL2_T12 Promedio Monto de deuda en la linea de avances en cuotas en la TC en el mes X
UsoLI_T12 Promedio Monto de deuda en la linea de compras internacionales en la TC en el mes X

Fase 1: Business Understanding¶

Objetivo de negocio

El objetivo principal del negocio es entender cómo se comportan los clientes del banco Monopoly para crear estrategias de marketing más efectivas en este nuevo mercado. Para lograrlo, vamos a analizar la información de la base de datos, centrándonos en dos aspectos clave: el nivel de ingresos de los clientes y su tipo de comportamiento de consumo. En este caso las variables a utilizar son (variable "SUBSEGMENTO") (variable "CUPO_L1").

Estas dos variables nos permitirán agrupar a los clientes en diferentes categorías según sus ingresos y hábitos de consumo. Esto nos dará una visión más clara de quiénes son nuestros clientes y cómo se comportan.

Una vez que tengamos estos grupos identificados, podremos crear estrategias de marketing específicas para cada uno. Por ejemplo, podemos diseñar productos y servicios personalizados para atender las necesidades particulares de cada grupo o lanzar campañas de marketing dirigidas exclusivamente a ellos.

El objetivo final es mejorar la experiencia de nuestros clientes en el banco Monopol y observar un aumento en su satisfacción.Finalmente esperamos que esto contribuya a incrementar los ingresos y la rentabilidad del banco.

Fase 2: Data Understanding¶

Librerias¶

In [1]:
# Insertar cuantos bloques de código consideren necesarios

# Se recomienda obtener estadísticos descriptivos para apoyar hipótesis inferenciales.
# Reconocer la naturaleza de los datos y como tratarlos en etapas posteriores y dar ideas de como se podría transformar.
# Identificar MissingValues, outliers, medidas de posición, medidas de dispersión etc.
In [2]:
!pip install gdown
!pip install plotly

import pandas as pd
import numpy as np
import gdown
import matplotlib.pyplot as plt
import seaborn as sb
import plotly.express as px

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
Requirement already satisfied: gdown in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (4.7.1)
Requirement already satisfied: filelock in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from gdown) (3.12.3)
Requirement already satisfied: requests[socks] in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from gdown) (2.31.0)
Requirement already satisfied: six in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from gdown) (1.16.0)
Requirement already satisfied: tqdm in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from gdown) (4.66.1)
Requirement already satisfied: beautifulsoup4 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from gdown) (4.12.2)
Requirement already satisfied: soupsieve>1.2 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from beautifulsoup4->gdown) (2.3.2.post1)
Requirement already satisfied: typing-extensions>=4.7.1 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from filelock->gdown) (4.7.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from requests[socks]->gdown) (2.0.12)
Requirement already satisfied: idna<4,>=2.5 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from requests[socks]->gdown) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from requests[socks]->gdown) (1.26.15)
Requirement already satisfied: certifi>=2017.4.17 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from requests[socks]->gdown) (2023.7.22)
Requirement already satisfied: PySocks!=1.5.7,>=1.5.6 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from requests[socks]->gdown) (1.7.1)
Requirement already satisfied: plotly in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (5.16.1)
Requirement already satisfied: tenacity>=6.2.0 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from plotly) (8.2.3)
Requirement already satisfied: packaging in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from plotly) (23.1)
In [3]:
!pip install fancyimpute
from fancyimpute import IterativeImputer
Requirement already satisfied: fancyimpute in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (0.7.0)
Requirement already satisfied: knnimpute>=0.1.0 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (0.1.0)
Requirement already satisfied: scikit-learn>=0.24.2 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (1.0.2)
Requirement already satisfied: cvxpy in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (1.3.2)
Requirement already satisfied: cvxopt in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (1.3.2)
Requirement already satisfied: pytest in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (7.4.2)
Requirement already satisfied: nose in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from fancyimpute) (1.3.7)
Requirement already satisfied: six in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from knnimpute>=0.1.0->fancyimpute) (1.16.0)
Requirement already satisfied: numpy>=1.10 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from knnimpute>=0.1.0->fancyimpute) (1.21.6)
Requirement already satisfied: scipy>=1.1.0 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from scikit-learn>=0.24.2->fancyimpute) (1.8.0)
Requirement already satisfied: joblib>=0.11 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from scikit-learn>=0.24.2->fancyimpute) (1.3.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from scikit-learn>=0.24.2->fancyimpute) (3.2.0)
Requirement already satisfied: osqp>=0.4.1 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from cvxpy->fancyimpute) (0.6.3)
Requirement already satisfied: ecos>=2 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from cvxpy->fancyimpute) (2.0.12)
Requirement already satisfied: scs>=1.1.6 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from cvxpy->fancyimpute) (3.2.3)
Requirement already satisfied: setuptools>65.5.1 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from cvxpy->fancyimpute) (68.2.0)
Requirement already satisfied: iniconfig in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from pytest->fancyimpute) (2.0.0)
Requirement already satisfied: packaging in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from pytest->fancyimpute) (23.1)
Requirement already satisfied: pluggy<2.0,>=0.12 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from pytest->fancyimpute) (1.3.0)
Requirement already satisfied: exceptiongroup>=1.0.0rc8 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from pytest->fancyimpute) (1.1.2)
Requirement already satisfied: tomli>=1.0.0 in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from pytest->fancyimpute) (2.0.1)
Requirement already satisfied: qdldl in /opt/saturncloud/envs/saturn/lib/python3.9/site-packages (from osqp>=0.4.1->cvxpy->fancyimpute) (0.1.7.post0)

Carga de datos¶

In [4]:
#carga de la carpeta drive
#se demora 30 seg
url = 'https://drive.google.com/drive/folders/1KyhbT-bw83JpbtOSWI7aDn3gWHF_OTV_?usp=sharing'


gdown.download_folder(url, quiet=True, use_cookies=False)
Out[4]:
['/home/jovyan/workspace/machine_learning/Base_clientes_Monopoly_descripcion.xlsx',
 '/home/jovyan/workspace/machine_learning/Base_clientes_Monopoly_sample.xlsx',
 '/home/jovyan/workspace/machine_learning/Base_clientes_Monopoly.xlsx',
 '/home/jovyan/workspace/machine_learning/descarga (1).png',
 '/home/jovyan/workspace/machine_learning/descarga (2).png',
 '/home/jovyan/workspace/machine_learning/ET221_1_MLY0100.pdf.pdf',
 '/home/jovyan/workspace/machine_learning/ET221_2_MLY0100.pdf.pdf',
 '/home/jovyan/workspace/machine_learning/ET221_3A_MLY0100.pdf.pdf',
 '/home/jovyan/workspace/machine_learning/ET221_4A_MLY0100.pdf.pdf',
 '/home/jovyan/workspace/machine_learning/ET221_5A_MLY0100.pdf.pdf',
 '/home/jovyan/workspace/machine_learning/monopoly_entrega1.ipynb',
 '/home/jovyan/workspace/machine_learning/monopoly_esqueleto.ipynb',
 '/home/jovyan/workspace/machine_learning/monopoly1.ipynb']
In [5]:
#data monopoly completa

''' data = pd.read_excel('/content/machine_learning/Base_clientes_Monopoly.xlsx', index_col=0) '''
Out[5]:
" data = pd.read_excel('/content/machine_learning/Base_clientes_Monopoly.xlsx', index_col=0) "
In [6]:
#data monopoly recortada para pruebas
#se demora 1 min
data = pd.read_excel('machine_learning/Base_clientes_Monopoly_sample.xlsx', index_col=0)

Funciones¶

In [7]:
## funcion para dar muestra de detalles del dataset
def check(df):
    l=[]
    columns=df.columns
    for col in columns:
        dtypes=df[col].dtypes
        nunique=df[col].nunique()
        sum_null=df[col].isnull().sum()
        percen_null=round(sum_null/len(df[col])*100, 4)

        l.append([col,dtypes,nunique,sum_null,percen_null])
    df_check=pd.DataFrame(l)
    df_check.columns=['column','dtypes','nunique','sum_null','percen_null']
    return df_check
In [8]:
#funcion para separar las columnas con datos de usaurio y los datos por mes
def mon_column(df):
  columns1=[]
  columns2=[]
  for column in df.columns.values:
    if column[-4:-1] in ("_T0","_T1"):
      columns2.append(column)
    else:
      columns1.append(column)
  df1=df[columns1]
  df2=df[columns2]


  return(df1,df2)
In [9]:
#funcion para obtener datos de usuario y los datos de enero para analisis
def datosUsuariEnero(df):

  columns2=[]
  for column in df.columns.values:
    if ((column[-4:-1] not in ("_T0","_T1")) or (column[-4:] in ("_T01",))):
      columns2.append(column)
  df2=df[columns2]

  return(df2)
In [10]:
def out_zscore(data):
    outliers = []
    zscore = []
    threshold = 3
    mean = np.mean(data)
    std = np.std(data)

    # Check if std is not zero before calculating z-scores
    if std != 0:
        for i in data:
            z_score = (i - mean) / std
            zscore.append(z_score)
            if np.abs(z_score) > threshold:
                outliers.append(i)

    return len(outliers)
In [11]:
def out_zscore2(data):
    global outliers, zscore
    outliers = []
    zscore = []
    threshold = 3
    mean = np.mean(data)
    std = np.std(data)
    for i in data:
        z_score = (i - mean) / std
        zscore.append(z_score)
        if np.abs(z_score) > threshold:
            outliers.append(i)
    return outliers, zscore
In [12]:
def find_outliers_zscore(data, threshold=3):
    outliers_count = []

    for column in data.columns:
        col_data = data[column]
        num_outliers = out_zscore(col_data)
        outliers_count.append((column, num_outliers))

    outliers_df = pd.DataFrame(outliers_count, columns=['Column', 'Outliers'])
    return outliers_df
In [13]:
def out_iqr(data):
    outliers = []
    iqr_values = []

    # Calculate the IQR
    q1 = np.percentile(data, 25)
    q3 = np.percentile(data, 75)
    iqr = q3 - q1

    # Define the lower and upper bounds for outliers
    lower_bound = q1 - 1.5 * iqr
    upper_bound = q3 + 1.5 * iqr

    # Check for outliers and store them
    for i in data:
        if i < lower_bound or i > upper_bound:
            outliers.append(i)

    return len(outliers)
In [14]:
def out_iqr_lh(df , column):
    global lower,upper
    q25, q75 = np.quantile(df[column], 0.25), np.quantile(df[column], 0.75)
    # calculate the IQR
    iqr = q75 - q25
    # calculate the outlier cutoff
    cut_off = iqr * 1.5
    # calculate the lower and upper bound value
    lower, upper = q25 - cut_off, q75 + cut_off
    print('The IQR is',iqr)
    print('The lower bound value is', lower)
    print('The upper bound value is', upper)
    # Calculate the number of records below and above lower and above bound value respectively
    df1 = df[df[column] > upper]
    df2 = df[df[column] < lower]
    return print('Total number of outliers are', df1.shape[0]+ df2.shape[0])

EDA Exploratory Data Analysis¶

In [15]:
#Primeras lineas del DF
data.head()
Out[15]:
Subsegmento Sexo Region Edad Renta Antiguedad Internauta Adicional Dualidad Monoproducto ... ColMx_T01 PagoNac_T01 PagoInt_T01 EeccNac_T01 EeccInt_T01 UsoL1_T01 UsoL2_T01 UsoLI_T01 IndRev_T01 target
Id
27778 210 M 9.0 28 436069.0 35 1 0 1 0 ... 0.0 14181 0.0 53539 0.0 53539.00 218399 0.0 R 0
37220 210 H 13.0 24 664366.0 20 1 0 0 0 ... 0.0 9000 0.0 246496 0.0 246496.00 115364 0.0 R 0
5289 210 M 12.0 28 485999.0 16 1 0 1 0 ... 0.0 20550 0.0 80823 0.0 79853.00 172986 0.0 R 0
24673 220 H NaN 25 NaN 14 0 0 0 0 ... 0.0 0 0.0 15249 0.0 15249.00 6966 0.0 R 0
27929 220 M 4.0 27 NaN 14 0 0 0 0 ... 0.0 70000 0.0 93591 0.0 36311.63 17949 0.0 R 0

5 rows × 573 columns

In [16]:
dfnuevo= datosUsuariEnero(data)
dfnuevo
Out[16]:
Subsegmento Sexo Region Edad Renta Antiguedad Internauta Adicional Dualidad Monoproducto ... ColMx_T01 PagoNac_T01 PagoInt_T01 EeccNac_T01 EeccInt_T01 UsoL1_T01 UsoL2_T01 UsoLI_T01 IndRev_T01 target
Id
27778 210 M 9.0 28 436069.0 35 1 0 1 0 ... 0.0 14181 0.0 53539 0.0 53539.00 218399 0.0 R 0
37220 210 H 13.0 24 664366.0 20 1 0 0 0 ... 0.0 9000 0.0 246496 0.0 246496.00 115364 0.0 R 0
5289 210 M 12.0 28 485999.0 16 1 0 1 0 ... 0.0 20550 0.0 80823 0.0 79853.00 172986 0.0 R 0
24673 220 H NaN 25 NaN 14 0 0 0 0 ... 0.0 0 0.0 15249 0.0 15249.00 6966 0.0 R 0
27929 220 M 4.0 27 NaN 14 0 0 0 0 ... 0.0 70000 0.0 93591 0.0 36311.63 17949 0.0 R 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
38406 220 H 13.0 22 88214.0 9 1 0 0 0 ... 0.0 0 0.0 41496 0.0 0.00 30184 0.0 T 0
7159 160 H 13.0 42 506029.0 34 1 0 0 0 ... 0.0 8000 0.0 254387 0.0 254387.00 0 0.0 R 0
9427 170 H 13.0 39 1181631.0 86 1 0 0 0 ... 0.0 30000 0.0 27182 0.0 27182.00 0 0.0 R 0
42142 160 H 8.0 60 346232.0 31 0 0 1 0 ... 0.0 5000 0.0 212699 0.0 212699.00 47272 0.0 R 1
5740 170 M 13.0 44 646476.0 84 1 0 1 0 ... 0.0 0 0.0 72033 0.0 72033.00 39052 0.0 T 0

5112 rows × 67 columns

In [17]:
#Datos del DF
data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5112 entries, 27778 to 5740
Columns: 573 entries, Subsegmento to target
dtypes: float64(505), int64(55), object(13)
memory usage: 22.4+ MB
In [18]:
# Tamaño de Filas y Columnas del DF

data.shape
Out[18]:
(5112, 573)
In [19]:
#separacion de los datos por usuario y datos registros por mes

data_cliente,data_mensual = mon_column(data)
print(data_cliente.shape)
print(data_mensual.shape)
(5112, 21)
(5112, 552)

Analis de datos de Clientes

In [20]:
#Atravez de la funcion Check se realiza un resumen del tipo de dato por columna,
# la cantidad de datos unicos, la cantidad de nulos, y el % de nulos respecto
# al total
check(data_cliente)
Out[20]:
column dtypes nunique sum_null percen_null
0 Subsegmento int64 8 0 0.0000
1 Sexo object 2 0 0.0000
2 Region float64 13 10 0.1956
3 Edad int64 72 0 0.0000
4 Renta float64 3561 1353 26.4671
5 Antiguedad int64 175 0 0.0000
6 Internauta int64 2 0 0.0000
7 Adicional int64 2 0 0.0000
8 Dualidad int64 2 0 0.0000
9 Monoproducto int64 2 0 0.0000
10 Ctacte int64 2 0 0.0000
11 Consumo int64 2 0 0.0000
12 Hipotecario int64 2 0 0.0000
13 Debito int64 2 0 0.0000
14 CambioPin float64 1 1921 37.5782
15 Cuentas int64 5 0 0.0000
16 TC int64 7 0 0.0000
17 CUPO_L1 int64 1490 0 0.0000
18 CUPO_L2 float64 715 0 0.0000
19 CUPO_MX int64 745 0 0.0000
20 target int64 2 0 0.0000

Se puede apreciar que en este tramo de datos existen tres columnas con datos nulos.

  1. Región: Los nulos representan menos del 1 % de los datos, por lo que se pueden eliminar sin afectar significativamente el tamaño de la muestra.
  2. Renta: Los nulos representan el 26 % de los datos, lo que es una proporción considerable. Para evitar que los datos faltantes afecten los resultados del análisis, se plantea imputarlos utilizando técnicas como MICE.
  3. CambioPin: En este caso, los valores nulos se pueden interpretar como que el cliente no realizó el cambio de pin. Por lo tanto, se plantea reemplazarlos por el valor "0".
In [21]:
#descripcion estadistica de los datos del cliente
data_cliente.describe()
Out[21]:
Subsegmento Region Edad Renta Antiguedad Internauta Adicional Dualidad Monoproducto Ctacte Consumo Hipotecario Debito CambioPin Cuentas TC CUPO_L1 CUPO_L2 CUPO_MX target
count 5112.000000 5102.000000 5112.000000 3.759000e+03 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 3191.0 5112.000000 5112.000000 5.112000e+03 5.112000e+03 5112.000000 5112.000000
mean 181.839397 10.823795 38.787559 6.589134e+05 39.120696 0.680164 0.260172 0.369523 0.068466 0.920970 0.001565 0.139476 0.874804 1.0 1.391432 1.721440 1.116222e+06 3.219817e+05 1376.821401 0.090571
std 28.483270 3.389346 13.438289 3.967115e+05 36.290536 0.466458 0.438771 0.482723 0.252569 0.269812 0.039532 0.346476 0.330973 0.0 0.538436 0.862639 1.045975e+06 7.642932e+05 1573.067873 0.287026
min 151.000000 1.000000 19.000000 1.000000e+00 6.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.0 1.000000 1.000000 5.000000e+04 0.000000e+00 0.000000 0.000000
25% 160.000000 9.000000 28.000000 4.188580e+05 14.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.0 1.000000 1.000000 4.000000e+05 1.000000e+03 300.000000 0.000000
50% 170.000000 13.000000 35.000000 5.636170e+05 26.000000 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.0 1.000000 2.000000 8.000000e+05 1.000000e+05 1000.000000 0.000000
75% 210.000000 13.000000 46.000000 8.068225e+05 54.000000 1.000000 1.000000 1.000000 0.000000 1.000000 0.000000 0.000000 1.000000 1.0 2.000000 2.000000 1.530000e+06 2.200000e+05 1831.500000 0.000000
max 811.000000 13.000000 93.000000 5.790824e+06 312.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.0 5.000000 7.000000 1.049400e+07 1.116800e+07 19600.000000 1.000000
In [22]:
#mapa de calor de correlaciones en datos de clientes
plt.figure(figsize = (15,8))
sb.heatmap(data_cliente.corr().round(3), cmap='coolwarm', annot=True)
plt.title="Mapa Calor"
plt.show()
No description has been provided for this image
In [23]:
#Grafico de relacion entre variables
df_subset = data_cliente.sample(frac=0.02)
print(len(df_subset), df_subset.columns)
print(df_subset.shape)
sb.pairplot(df_subset)
102 Index(['Subsegmento', 'Sexo', 'Region', 'Edad', 'Renta', 'Antiguedad',
       'Internauta', 'Adicional', 'Dualidad', 'Monoproducto', 'Ctacte',
       'Consumo', 'Hipotecario', 'Debito', 'CambioPin', 'Cuentas', 'TC',
       'CUPO_L1', 'CUPO_L2', 'CUPO_MX', 'target'],
      dtype='object')
(102, 21)
Out[23]:
<seaborn.axisgrid.PairGrid at 0x7ff2dbf1af10>
No description has been provided for this image

Analis de datos de registros por mes de Clientes

In [24]:
#Atravez de la funcion Check se realiza un resumen del tipo de dato por columna,
# la cantidad de datos unicos, la cantidad de nulos, y el % de nulos respecto
# al total
data_mensual_check=check(data_mensual)
data_mensual_check
Out[24]:
column dtypes nunique sum_null percen_null
0 FlgAct_T12 float64 2 836 16.3537
1 FlgActCN_T12 float64 2 836 16.3537
2 FlgActCI_T12 float64 2 836 16.3537
3 FlgActAN_T12 float64 2 836 16.3537
4 FlgActAI_T12 float64 2 836 16.3537
... ... ... ... ... ...
547 EeccInt_T01 float64 305 0 0.0000
548 UsoL1_T01 float64 4435 0 0.0000
549 UsoL2_T01 int64 3314 0 0.0000
550 UsoLI_T01 float64 313 0 0.0000
551 IndRev_T01 object 3 0 0.0000

552 rows × 5 columns

In [25]:
#cantidad de columnas que continene datos nulos
len(data_mensual_check[data_mensual_check["sum_null"]>0])
Out[25]:
506
In [26]:
#cantidad de columnas que el % de nulos es mayor que el 10%
len(data_mensual_check[data_mensual_check["percen_null"]>10])
Out[26]:
138
In [27]:
#analizando datos de colunas IndRev_TXX del tipo Object
data["IndRev_T01"].unique()
Out[27]:
array(['R', 'P', 'T'], dtype=object)

Se determina que existen 506 de 552 columnas con valores nulos.

Ademas, 138 columnas de 552 el % de nulos es mayor que el 10%.

Como los valores registrados en este tramos de la infomacion corresponde a numericos se pueden aplicar MICE para su imputacion.

Tambien se debe considerar realizar un transformacion previa en las columnas "IndRev_TXX" antes de la operacion sugerida.

In [28]:
#Descripcion estadistica de los Registros mensuales de Enero

data_mensual.iloc[:,-46:].describe()
Out[28]:
FlgAct_T01 FlgActCN_T01 FlgActCI_T01 FlgActAN_T01 FlgActAI_T01 FlgActPAT_T01 FlgActCCPC_T01 FlgActCCOT_T01 FlgActCOL_T01 Fac_T01 ... ColL2AC_T01 ColL2CC_T01 ColMx_T01 PagoNac_T01 PagoInt_T01 EeccNac_T01 EeccInt_T01 UsoL1_T01 UsoL2_T01 UsoLI_T01
count 5112.000000 5112.00000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5112.000000 5.112000e+03 ... 5.112000e+03 5.112000e+03 5.112000e+03 5.112000e+03 5.112000e+03 5.112000e+03 5112.000000 5.112000e+03 5.112000e+03 5112.000000
mean 0.664710 0.58529 0.040102 0.030908 0.001956 0.133803 0.286972 0.101526 0.001565 7.163727e+04 ... 6.247437e+04 4.107607e+04 5.530910e+03 7.264162e+04 1.208558e+03 1.913094e+05 7.596050 1.817260e+05 1.291747e+05 8.987338
std 0.472138 0.49272 0.196217 0.173085 0.044190 0.340474 0.452393 0.302053 0.039532 1.412821e+05 ... 4.203266e+05 9.948940e+04 5.674680e+04 1.379294e+05 2.532578e+04 2.845051e+05 122.800419 2.863325e+05 4.320962e+05 126.358721
min 0.000000 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 -1.199000e+05 ... 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 -8.769960e+05 -4885.000000 -8.769960e+05 -2.000000e+00 -4652.500000
25% 0.000000 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000e+00 ... 0.000000e+00 0.000000e+00 0.000000e+00 5.000000e+03 0.000000e+00 3.128575e+04 0.000000 1.664075e+04 0.000000e+00 0.000000
50% 1.000000 1.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.779750e+04 ... 0.000000e+00 0.000000e+00 0.000000e+00 3.300000e+04 0.000000e+00 9.074350e+04 0.000000 7.974000e+04 2.851650e+04 0.000000
75% 1.000000 1.00000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 8.845400e+04 ... 0.000000e+00 4.008150e+04 0.000000e+00 8.891975e+04 0.000000e+00 2.364485e+05 0.000000 2.276278e+05 9.524400e+04 0.000000
max 1.000000 1.00000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 2.793659e+06 ... 1.013884e+07 1.472740e+06 1.762587e+06 3.066190e+06 1.225290e+06 3.202962e+06 3341.650000 3.511191e+06 1.000609e+07 3341.650000

8 rows × 45 columns

In [29]:
#mapa de calor de correlaciones en los Registros mensuales de Enero
plt.figure(figsize = (30,30))
sb.heatmap(data_mensual.iloc[:,-46:].corr().round(3), cmap='coolwarm', annot=True)
plt.title="Mapa Calor"
plt.show()
No description has been provided for this image
In [30]:
#Grafico de relacion entre variables
df_subset2 = data_mensual.iloc[:,-46:].sample(frac=0.02)
print(len(df_subset2), df_subset2.columns)
print(df_subset2.shape)
sb.pairplot(df_subset2)
102 Index(['FlgAct_T01', 'FlgActCN_T01', 'FlgActCI_T01', 'FlgActAN_T01',
       'FlgActAI_T01', 'FlgActPAT_T01', 'FlgActCCPC_T01', 'FlgActCCOT_T01',
       'FlgActCOL_T01', 'Fac_T01', 'Txs_T01', 'FacCN_T01', 'TxsCN_T01',
       'FacCI_T01', 'TxsCI_T01', 'FacAN_T01', 'TxsAN_T01', 'FacAI_T01',
       'TxsAI_T01', 'FacPAT_T01', 'TxsPAT_T01', 'FacCCPC_T01', 'TxsCCPC_T01',
       'FacCCOT_T01', 'TxsCCOT_T01', 'FacCOL_T01', 'TxsCOL_T01',
       'FacDebCom_T01', 'TxsDebCom_T01', 'FacDebAtm_T01', 'TxsDebAtm_T01',
       'Col_T01', 'ColL1T0_T01', 'ColL1TE_T01', 'ColL2T0_T01', 'ColL2AC_T01',
       'ColL2CC_T01', 'ColMx_T01', 'PagoNac_T01', 'PagoInt_T01', 'EeccNac_T01',
       'EeccInt_T01', 'UsoL1_T01', 'UsoL2_T01', 'UsoLI_T01', 'IndRev_T01'],
      dtype='object')
(102, 46)
Out[30]:
<seaborn.axisgrid.PairGrid at 0x7ff2c679a7f0>
No description has been provided for this image

Fase 3: Data Preparation¶

Imputación¶


In [31]:
#se remplazan los nulos por "0" en la columna "CambioPin"
data_imputada_CP= data.copy()
data_imputada_CP["CambioPin"].fillna(0, inplace=True)
data_imputada_CP["CambioPin"]
Out[31]:
Id
27778    1.0
37220    0.0
5289     1.0
24673    0.0
27929    1.0
        ... 
38406    1.0
7159     0.0
9427     1.0
42142    1.0
5740     0.0
Name: CambioPin, Length: 5112, dtype: float64
In [32]:
# Se utiliza label Encoder para transformar a valores numeros las columnas categoricas.
# IMPORTANTE: se utiliza LabelEncoder para poder ser procesado con MICE, en un paso posterior se debe pasar a ONE HOT encoding
data_imputada_LE= data_imputada_CP.copy()
le = LabelEncoder()
columns=data_imputada_LE.select_dtypes(include='object').columns.values
for column in columns:

  mascara=data_imputada_LE[column].isnull()
  data_imputada_LE[column] = le.fit_transform(data_imputada_LE[column])
  data_imputada_LE[column][mascara]=np.nan
/tmp/ipykernel_10213/1418396582.py:10: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  data_imputada_LE[column][mascara]=np.nan
In [33]:
#Se separa los datos del tipo float e Int para poder se procesador con MICE
#ya que no acepta String
data_imputada_MICE=data_imputada_LE.select_dtypes(include=["float64","int64"])
In [34]:
#Se crea una copia recortada del DF para que no sature la RAM de Colaborate
data_imputada_MICE=data_imputada_MICE.sample(frac=0.5)
In [35]:
#Se cuenta la cantidad total de nulos antes del MICE
data_imputada_MICE.isnull().sum().sum()
Out[35]:
60374
In [36]:
#se extra el mayor y menor valor de cada columna dentro de la tabla para
#establecerlo como parametro en la funcion de MICE IterativeImputer

min = data_imputada_MICE.iloc[:,:].min(axis=0)
max = data_imputada_MICE.iloc[:,:].max(axis=0)

#en las tablas de valores de 0 y 1 si en la muestra se estra un valor unico,
#es decir, solo se extrajo 0, para que no produsca un error se define el max
# y el minimo de forma manual en 1 y 0 respectivamente

for i in range(len(min)):
  if min[i]>=max[i]:
    min[i]=0
    max[i]=1


print(f"valor minimo {min}")
print("\n------------------\n")
print(f"valor maximo {max}")
valor minimo Subsegmento       151.00
Sexo                0.00
Region              1.00
Edad               19.00
Renta               1.00
                 ...    
UsoL1_T01     -876996.00
UsoL2_T01          -2.00
UsoLI_T01        -437.16
IndRev_T01          0.00
target              0.00
Length: 573, dtype: float64

------------------

valor maximo Subsegmento        811.00
Sexo                 1.00
Region              13.00
Edad                93.00
Renta          5790824.00
                  ...    
UsoL1_T01      3511191.00
UsoL2_T01      8315098.00
UsoLI_T01         2439.21
IndRev_T01           2.00
target               1.00
Length: 573, dtype: float64
In [37]:
# Crear una instancia de IterativeImputer
#parametros:
#max_iter= 3  maxima cantidad de itineraciones igual a 3
#min_value= min  se le entrega el minimo ya existente en la DB
#min_value= min  se le entrega el maximo ya existente en la DB
#se entregan los valores min y max para que los resultados no se desboden
# y genere un error

imputer=IterativeImputer( max_iter= 3, min_value=min, max_value=max)

imputed_np = imputer.fit_transform(data_imputada_MICE)
columns_names_df = data_imputada_MICE.columns.values
data_imputada_ok = pd.DataFrame(imputed_np, columns = columns_names_df)

data_imputada_ok
/opt/saturncloud/envs/saturn/lib/python3.9/site-packages/sklearn/impute/_iterative.py:699: ConvergenceWarning: [IterativeImputer] Early stopping criterion not reached.
  warnings.warn(
Out[37]:
Subsegmento Sexo Region Edad Renta Antiguedad Internauta Adicional Dualidad Monoproducto ... ColMx_T01 PagoNac_T01 PagoInt_T01 EeccNac_T01 EeccInt_T01 UsoL1_T01 UsoL2_T01 UsoLI_T01 IndRev_T01 target
0 220.0 1.0 13.0 24.0 4.921897e+05 12.0 1.0 1.0 0.0 0.0 ... 0.0 5000.0 0.00 61162.0 0.00 41162.0 0.0 0.00 1.0 0.0
1 151.0 0.0 2.0 62.0 9.227165e+05 153.0 0.0 0.0 0.0 1.0 ... 0.0 36000.0 0.00 1210977.0 0.00 1231027.0 308965.0 0.00 1.0 0.0
2 160.0 1.0 13.0 45.0 2.665800e+05 120.0 1.0 1.0 1.0 0.0 ... 0.0 8145.0 30065.22 17101.0 -0.72 22601.0 46186.0 -0.72 2.0 0.0
3 160.0 0.0 13.0 51.0 5.817030e+05 24.0 1.0 0.0 0.0 0.0 ... 0.0 16000.0 0.00 270298.0 0.00 276298.0 80885.0 0.00 1.0 0.0
4 220.0 1.0 7.0 27.0 4.522378e+05 19.0 0.0 0.0 0.0 0.0 ... 0.0 10000.0 0.00 75236.0 0.00 75236.0 62599.0 0.00 1.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2551 170.0 1.0 7.0 41.0 8.565990e+05 11.0 0.0 0.0 1.0 0.0 ... 0.0 20000.0 0.00 17728.0 0.00 -2272.0 94637.0 0.00 1.0 1.0
2552 160.0 1.0 6.0 60.0 9.892800e+04 8.0 0.0 0.0 0.0 0.0 ... 0.0 42182.0 0.00 42186.0 0.00 42186.0 0.0 0.00 0.0 0.0
2553 220.0 1.0 2.0 29.0 4.395210e+05 27.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.00 19732.0 0.00 19732.0 19266.0 0.00 0.0 0.0
2554 160.0 0.0 13.0 34.0 5.915130e+05 7.0 0.0 0.0 1.0 0.0 ... 0.0 0.0 0.00 482387.0 0.00 482387.0 79839.0 0.00 1.0 0.0
2555 170.0 0.0 13.0 35.0 1.135570e+06 36.0 1.0 0.0 0.0 0.0 ... 0.0 154127.0 0.00 148701.0 0.00 148701.0 0.0 0.00 1.0 0.0

2556 rows × 573 columns

In [38]:
#se comprueba la cantidad final de nulos luego de MICE
data_imputada_ok.isnull().sum().sum()
Out[38]:
0

Outliers¶

Para analizar los outliers, se tomó la decisión de utilizar dos métodos ampliamente aceptados, el Z-Score y el IQR (Rango Intercuartílico). Estos métodos proporcionarán resultados diversos y más apropiados según las características de los datos en cada columna, permitiendo una evaluación más completa de los valores atípicos y su significado en el contexto de los datos.

Utilizar tanto el método del IQR como el Z-Score para el análisis de outliers es beneficioso porque:

El IQR es robusto y eficaz para identificar valores extremos en distribuciones no normales o sesgadas. El Z-Score estandariza los datos y proporciona una medida cuantitativa de rareza. Combinar ambos métodos proporciona mayor confiabilidad al identificar valores atípicos y se adapta a diferentes distribuciones de datos.

In [39]:
#Se crea un filtro de tablas que contengan más de 3 valores unicos
#dejando fuera columnas de [0,1] y de clasificacion como IndRev_TXX
df_filtro=check(data)

filtro=df_filtro[df_filtro["nunique"]>3]["column"]
filtro
Out[39]:
0      Subsegmento
2           Region
3             Edad
4            Renta
5       Antiguedad
          ...     
566    EeccNac_T01
567    EeccInt_T01
568      UsoL1_T01
569      UsoL2_T01
570      UsoLI_T01
Name: column, Length: 430, dtype: object
In [40]:
#Se copia la tabla de datos imputados para comenzar a analizar outliers
elimOutliers = data_imputada_ok.copy()

Zscore¶

In [41]:
#Se aplica la funcion declarada mas arriba para detectar outliers utilizando zscore
outliers_zscore = find_outliers_zscore(elimOutliers[filtro])
In [43]:
# se gráfican las 12 columnas con mas Outliers encontrados

melted_df = pd.melt(
    outliers_zscore, id_vars="Column", value_vars="Outliers", var_name="Metric"
)


filtered_melted_df=melted_df.sort_values("value",ascending=False).head(12)


# Gráfico de barras
plt.figure(figsize=(20, 5))
fig=sb.barplot(x = filtered_melted_df["Column"], y = filtered_melted_df["value"],color = "blue")
plt.xlabel("Nombre columna")
plt.ylabel("Numero de outliers")
plt.bar_label(fig.containers[0])
plt.legend()
plt.show()
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No description has been provided for this image
In [45]:
filtered_melted_df.sort_values("value",ascending=False)
Out[45]:
Column Metric value
86 FacAN_T10 Outliers 250
96 FacCOL_T10 Outliers 250
104 ColL2T0_T10 Outliers 249
149 UsoLI_T09 Outliers 191
131 FacCOL_T09 Outliers 190
143 PagoNac_T09 Outliers 190
148 UsoL2_T09 Outliers 190
126 TxsPAT_T09 Outliers 189
136 Col_T09 Outliers 189
140 ColL2AC_T09 Outliers 189
142 ColMx_T09 Outliers 189
139 ColL2T0_T09 Outliers 188

Para mostrar en mayor detalle los datos observados en el grafico, se tomaron las columnas mas extremas y se les aplico un histograma, a la vez marcando una posible seccion de outlier.

In [44]:
outliers, zscore = out_zscore2(elimOutliers.FacCN_T10)

# Crea histograma de zscore
plt.figure(figsize=(10, 5))
sb.histplot(zscore, bins=20, kde=True, color='blue')
plt.xlabel('Z-Score')
plt.ylabel('Frequency')
shaded_upper_limit = 10  # Ajusta tope superior
# Agrega seccion demarcada de outliers
if len(outliers) > 0:
    plt.axvspan(xmin=2, xmax=shaded_upper_limit, alpha=0.2, color='red')


plt.legend()
plt.show()
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No description has been provided for this image

Finalmente se grafico en boxplot la columna con mayor cantidad de outliers

In [47]:
sb.boxplot(x = elimOutliers['FacCN_T10'])
Out[47]:
<AxesSubplot:xlabel='FacCN_T10'>
No description has been provided for this image

IQR¶

Para el analisis utilizando IQR se realizo el mismo procedimiento de graficar outliers, analizar los extremos y graficar en boxplot el mas alto

In [48]:
iqr_results = [(column, out_iqr(elimOutliers[column])) for column in elimOutliers[filtro].columns]
iqr_df = pd.DataFrame(iqr_results, columns=['Column Name', 'IQR Outliers'])

filtered_iqr_df = iqr_df.sort_values("IQR Outliers",ascending=False).head(12)

# Gráfico de barras
plt.figure(figsize=(20, 5))
fig=sb.barplot(x = filtered_iqr_df["Column Name"], y = filtered_iqr_df["IQR Outliers"],color = "blue")
plt.xlabel("Nombre columna")
plt.ylabel("Numero de outliers")
plt.bar_label(fig.containers[0])
plt.legend()
plt.show()
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No description has been provided for this image
In [49]:
#listados de columnas con mas Outliers encontrados en el metodo IQR
filtered_iqr_df.sort_values("IQR Outliers",ascending=False)
Out[49]:
Column Name IQR Outliers
55 FacPAT_T11 634
58 TxsCCPC_T11 627
25 TxsCCOT_T12 617
24 FacCCOT_T12 616
92 FacCCPC_T10 614
91 TxsPAT_T10 575
23 TxsCCPC_T12 574
36 ColL2CC_T12 559
57 FacCCPC_T11 544
44 UsoLI_T12 538
59 FacCCOT_T11 533
41 EeccInt_T12 532
In [50]:
# Crea histograma de zscore
outliers, zscore = out_zscore2(elimOutliers.FacCCOT_T12)

# Create a histogram of the z-scores
plt.figure(figsize=(10, 5))
sb.histplot(zscore, bins=20, kde=True, color='blue')
plt.xlabel('Z-Score')
plt.ylabel('Frequency')
shaded_upper_limit = 10  # Ajusta tope superior

# Agrega seccion demarcada de outliers
if len(outliers) > 0:
    plt.axvspan(xmin=2, xmax=shaded_upper_limit, alpha=0.2, color='red')


plt.legend()
plt.show()
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No description has been provided for this image
In [51]:
sb.boxplot(x = elimOutliers['FacCCOT_T12'])
Out[51]:
<AxesSubplot:xlabel='FacCCOT_T12'>
No description has been provided for this image
In [52]:
elimOutliers['FacCCOT_T12'].min()
Out[52]:
0.0
In [53]:
elimOutliers['FacCCOT_T12'].max()
Out[53]:
9035980.0

Conclusiones Outliers¶

En el análisis de los datos con las tecnicas de Zscore y IQR se detectaron valores atípicos, es decir, valores que se alejan de la tendencia central de sus respectivas columnas. Estos valores, si bien son inusuales, no son imposibles. Por ejemplo, en la columna "FacCCOT_T12" (Promedio de monto facturado en compras en cuotas con tasa por el cliente en TC en el mes X), existe un registro único mayor que 500.000. Si bien es inusual que un cliente realice una compra de esa cantidad, esta dentro de los límites que se pueden facturar.

Por lo tanto, se decidió mantener estos valores para su estudio.

Normalización¶

Una vez procesados los datos, y al tener todos los valores numéricos, se decidió aplicar el método de escalado Min-Max para transformar los datos a un rango de 0 a 1.

In [54]:
#Se aplica MInMAxScaler para poder normalizar los datos de la tabla

data_normalizada=data_imputada_ok.copy()
nombre_columnas= data_imputada_MICE.columns.values
mmscaler = MinMaxScaler()
np_normalizado=mmscaler.fit_transform(data_normalizada)
data_normalizada = pd.DataFrame(np_normalizado,columns=nombre_columnas)
data_normalizada
Out[54]:
Subsegmento Sexo Region Edad Renta Antiguedad Internauta Adicional Dualidad Monoproducto ... ColMx_T01 PagoNac_T01 PagoInt_T01 EeccNac_T01 EeccInt_T01 UsoL1_T01 UsoL2_T01 UsoLI_T01 IndRev_T01 target
0 0.104545 1.0 1.000000 0.067568 0.084995 0.019608 1.0 1.0 0.0 0.0 ... 0.0 0.001631 0.000000 0.231776 0.151983 0.209234 2.405263e-07 0.151983 0.5 0.0
1 0.000000 0.0 0.083333 0.581081 0.159341 0.480392 0.0 0.0 0.0 1.0 ... 0.0 0.011741 0.000000 0.515842 0.151983 0.480386 3.715734e-02 0.151983 0.5 0.0
2 0.013636 1.0 1.000000 0.351351 0.046035 0.372549 1.0 1.0 1.0 0.0 ... 0.0 0.002656 0.024537 0.220890 0.151733 0.205004 5.554714e-03 0.151733 1.0 0.0
3 0.013636 0.0 1.000000 0.432432 0.100452 0.058824 1.0 0.0 0.0 0.0 ... 0.0 0.005218 0.000000 0.283444 0.151983 0.262818 9.727724e-03 0.151983 0.5 0.0
4 0.104545 1.0 0.500000 0.108108 0.078095 0.042484 0.0 0.0 0.0 0.0 ... 0.0 0.003261 0.000000 0.235253 0.151983 0.216999 7.528593e-03 0.151983 0.5 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2551 0.028788 1.0 0.500000 0.297297 0.147923 0.016340 0.0 0.0 1.0 0.0 ... 0.0 0.006523 0.000000 0.221045 0.151983 0.199336 1.138158e-02 0.151983 0.5 1.0
2552 0.013636 1.0 0.416667 0.554054 0.017083 0.006536 0.0 0.0 0.0 0.0 ... 0.0 0.013757 0.000000 0.227088 0.151983 0.209467 2.405263e-07 0.151983 0.0 0.0
2553 0.104545 1.0 0.083333 0.135135 0.075899 0.068627 0.0 0.0 0.0 0.0 ... 0.0 0.000000 0.000000 0.221540 0.151983 0.204350 2.317230e-03 0.151983 0.0 0.0
2554 0.013636 0.0 1.000000 0.202703 0.102146 0.003268 0.0 0.0 1.0 0.0 ... 0.0 0.000000 0.000000 0.335841 0.151983 0.309782 9.601929e-03 0.151983 0.5 0.0
2555 0.028788 0.0 1.000000 0.216216 0.196098 0.098039 1.0 0.0 0.0 0.0 ... 0.0 0.050267 0.000000 0.253403 0.151983 0.233740 2.405263e-07 0.151983 0.5 0.0

2556 rows × 573 columns

Fase 4: Modeling¶

Regresión¶

In [55]:
# Insertar cuantos bloques de código consideren necesarios

# Realizar tarea de regresión de datos orientado al caso entregado

Clasificación¶

In [56]:
# Insertar cuantos bloques de código consideren necesarios

# Realizar tarea de clasificación de datos orientado al caso entregado
In [ ]:
 

Fase 5: Evaluation¶

In [57]:
# Insertar cuantos bloques de código consideren necesarios

# Evaluar con las métricas que corresponda los mejores modelos, explicar cual es mejor para cada tarea y por qué

Fase 6: Deployment¶

In [58]:
# Insertar cuantos bloques de código consideren necesarios

# Realizar despliegue del modelo